package cn.edu.fudan.rule;

import cn.edu.fudan.type.DataItem;
import cn.edu.fudan.type.WaveletPerOrder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by 80494 on 2017/4/7.
 */
public class WaveletPre {
    public  WaveletPerOrder WaveletPre( List<DataItem> rawdatas) {

        List<Double> dataonly = new ArrayList<>();
        List<Double> zeroarray = new ArrayList<>();
        List<Integer> zerointarray = new ArrayList<>();


        DataItem test = new DataItem();

        int maxorder = (int) Math.ceil(Math.log(rawdatas.size()) / Math.log(2)); //get the possible max order

        //rawdatas=ZNorm(rawdatas); //do Z-normalization in order to


        for (int i = 0; i < Math.pow(2, maxorder); i++) { // fill 0 when the number of series points doesnt reach the 2^n
            zeroarray.add(i, 0.0);
            zerointarray.add(i, 0);
            if (i<rawdatas.size()) {
                dataonly.add(i, rawdatas.get(i).getValue());
            } else {
                dataonly.add(i, 0.0);
            }
        }
        double max = Collections.max(dataonly);
        double min = Collections.min(dataonly);
        int t=dataonly.size();
        int j=0;
        int q=1;
        for (int i=0;i<dataonly.size();i++){
            dataonly.set(i,(dataonly.get(i)-min)/(max-min));
        }


        //WaveletPerOrder waveletpre = new WaveletPerOrder(maxorder,t);//Initial waveletpresetation
        WaveletPerOrder waveletpre = new WaveletPerOrder();//Initial waveletpresetation

        waveletpre.addOrder(j,j);
        waveletpre.addSeries(dataonly,0);    //
        waveletpre.addCoeff(zeroarray,0);
        waveletpre.addDseries(zerointarray,0);
        while (q*2!=t){  //generate waveletpresentation
            j++;

            waveletpre.getOrder().add(j,j);
            waveletpre.getSeries().add(j,waveletpre.SeriesToSeries(waveletpre.getSeries().get(j-1)));
            waveletpre.getCoeff().add(j,waveletpre.SeriesToCoeff(waveletpre.getSeries().get(j-1)));
            waveletpre.getDseries().add(j,waveletpre.SeriesToDseries(waveletpre.getCoeff().get(j),10,0.0,1.0)); //有问题
            q=q*2;
        }

        return waveletpre;
    }

    private List<DataItem> ZNorm(List<DataItem> data){ //Z标准化
        List<DataItem> normdata = new ArrayList<>();
        double sum = 0;
        double squaresum = 0;
        double average = 0;
        double srd = 0;
        if (data.size()==0){
            return data;
        }
        for (int i = 0; i < data.size(); i++) {
            sum += data.get(i).getValue();
        }
        average = sum / data.size();
        for (int i = 0; i < data.size(); i++) {
            squaresum = (data.get(i).getValue() - average) * (data.get(i).getValue() - average);
        }
        srd = Math.sqrt(squaresum) / (data.size() - 1);
        normdata.addAll(data); //初始化
        for (int i = 0; i < data.size(); i++) {//Z-norm
            double t = (data.get(i).getValue()-average)/srd;
            normdata.get(i).setValue((t));
            normdata.get(i).setTimestamp(data.get(i).getTimestamp());

        }
        return normdata;
    }

}
